import 'dart:async';
import 'dart:collection';
import 'package:flutter/material.dart';
import 'package:x3_base_core/x3_base_core.dart';
import 'package:x3_component_core/enums/loading_status_enum.dart';
import 'package:x3_component_core/components/scroll_components/base_refresh_gridview_container_component.dart';
import 'package:x3_component_core/controller/base_refresh_controller.dart';

class BaseRefreshGirdViewComponent extends StatefulWidget {
  /// 请求的服务地址
  final String path;

  /// 请求的方式
  final BaseHttpMethodEnum method;

  /// 构建Item项
  final Widget Function(Map<String, dynamic> item, int index) buildItem;

  /// 是否是分页查询
  final bool isPaging;

  /// 刷新列表控制器
  final BaseRefreshController controller;

  /// 参数
  final Map<String, dynamic> params;

  /// 刷新数据加载完成事件
  final Function(List<Map<String, dynamic>> items) refreshDataLoadComplete;

  /// Loading加载完成事件 上拉加载专用，将每次加载到的数据回传
  final Function(List<Map<String, dynamic>> items) dataLoadComplete;

  /// 控制item间的间距
  final SliverGridDelegate gridDelegate;

  /// 由于有多个请求类型，每个类型的返回数据还不一定一样，过于奇葩，只能将数据整理对外，让外部处理
  /// 如果不为null 则调用，否则按照默认处理
  final List<dynamic> Function(BaseHttpResultModel result, {bool isRefresh}) initResultData;

  /// 每页显示多少条数
  final int pageSize;

  BaseRefreshGirdViewComponent({Key key, @required this.path, @required this.buildItem, @required this.controller, @required this.gridDelegate, this.method = BaseHttpMethodEnum.POST, this.isPaging = true, this.refreshDataLoadComplete, this.dataLoadComplete, this.params = const {}, this.initResultData, this.pageSize = 15}) : super(key: key);

  @override
  _BaseRefreshGirdViewComponentState createState() => _BaseRefreshGirdViewComponentState();
}

class _BaseRefreshGirdViewComponentState extends State<BaseRefreshGirdViewComponent> {
  /// 数据源
  List<Map<String, dynamic>> items;

  /// 判断是否加载完成
  LoadingStatusEnum loadingStatus;

  /// 当前是第几页
  int pageIndex = 1;

  /// 刷新控制器
  BaseRefreshController _controller;

  /// 获取当前的控制器
  BaseRefreshController get _effectiveController => widget.controller ?? _controller;

  /// 下拉刷新组件
  GlobalKey<RefreshIndicatorState> _refreshIndicatorState;

  @override
  void initState() {
    super.initState();
    loadingStatus = LoadingStatusEnum.LoadingComplete;
    if (widget.controller == null) {
      _controller = new BaseRefreshController();
    }
    _effectiveController.addListener(() {
      this._refreshIndicatorState.currentState.show();
    });
  }

  /// 获取数据
  Future<BaseHttpResultModel> _getItems() async {
    if (widget.path == null || widget.path.isEmpty) {
      return BaseHttpResultModel(BaseDioCodeUtil.success_code, true, [], null, null);
    }
    Map<String, dynamic> params = new HashMap();
    params.addAll(widget.params);
    params.addAll(_effectiveController.params);
    if (widget.isPaging == true) {
      Map<String, dynamic> pageParams = {'pageIndex': pageIndex, 'pageSize': widget.pageSize};
      params.addAll(pageParams);
    }
    BaseHttpResultModel result = await dioUtil.fetch(widget.path, method: widget.method, params: params);
    return result;
  }

  /// 刷新数据
  Future _onRefresh() async {
    pageIndex = 1;
    BaseHttpResultModel result = await _getItems();
    List<dynamic> datas = _initResultData(result, true);
    if (mounted == true) {
      setState(() {
        items = BaseDioCodeUtil.dynamicListToMapList(datas);
        loadingStatus = LoadingStatusEnum.LoadingComplete;
      });
    }
    if (widget.refreshDataLoadComplete != null) {
      widget.refreshDataLoadComplete(items);
    }
  }

  /// 加载更多
  Future _onLoading() async {
    if (loadingStatus == LoadingStatusEnum.Loading) return;
    if (mounted == true) {
      setState(() {
        loadingStatus = LoadingStatusEnum.Loading;
      });
    }
    pageIndex++;
    BaseHttpResultModel result = await _getItems();
    List<dynamic> datas = _initResultData(result, false);
    if (mounted == true) {
      if (datas.length == 0) {
        loadingStatus = LoadingStatusEnum.NoMore;
      } else {
        setState(() {
          items.addAll(BaseDioCodeUtil.dynamicListToMapList(datas));
          if (widget.dataLoadComplete != null) widget.dataLoadComplete(items);
          loadingStatus = LoadingStatusEnum.LoadingComplete;
        });
      }
    }
  }

  List<dynamic> _initResultData(BaseHttpResultModel result, bool isRefresh) {
    if (widget.initResultData != null) return widget.initResultData(result, isRefresh: isRefresh);
    if (result.success != true) return [];
    if (!(result.data is List)) return [];
    return result.data;
  }

  /// 构建widget
  @override
  Widget build(BuildContext context) {
    return BaseRefreshGridViewContainerComponent(
      gridDelegate: widget.gridDelegate,
      count: items == null ? 0 : items.length,
      builder: (BuildContext context, int index) {
        Map<String, dynamic> item = items[index];
        return widget.buildItem(item, index);
      },
      getRefreshIndicatorState: (GlobalKey<RefreshIndicatorState> refreshIndicatorState) {
        this._refreshIndicatorState = refreshIndicatorState;
      },
      onRefresh: () => _onRefresh(),
      isFirstLoading: items == null,
      needLoading: widget.isPaging,
      onLoading: () => _onLoading(),
      loadingStatus: loadingStatus,
    );
  }

  @override
  void dispose() {
    _effectiveController.dispose();
    super.dispose();
  }
}
